package com.java.support.redis;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.PreDestroy;
import java.lang.reflect.Method;

@Configuration
@PropertySource("classpath:redisConfig.properties")
public class RedisConfigure implements MethodInterceptor {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private JedisPool jedisPool;

    private static final String JEDISRESOURCE = "JedisResource";

    private static final String PREFIX = "cache";

    private static final String LOCATION = "classpath:redisConfig.properties";

    @Bean(name = JEDISRESOURCE)
    @ConfigurationProperties(prefix = PREFIX)
    public JedisResource JedisResource() {
        return new JedisResource();
    }

    @Bean
    public JedisPool jedisPool(@Qualifier(JEDISRESOURCE) JedisResource resource) {
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxIdle(resource.getMaxIdle());
        poolConfig.setMaxWaitMillis(resource.getMaxWait());
        poolConfig.setTestOnBorrow(resource.isTestOnBorrow());
        poolConfig.setMaxTotal(resource.getMaxActive());
        if (StringUtils.isEmpty(resource.getPassword())) {
            return new JedisPool(poolConfig, resource.getHost(), resource.getPort(), resource.getTimeout());
        } else {
            return new JedisPool(poolConfig, resource.getHost(), resource.getPort(), resource.getTimeout(), resource.getPassword());
        }
    }

    @PreDestroy
    public void destroy() {
        if (null != jedisPool) {
            jedisPool.destroy();
        }
    }

   /*  private Enhancer enhancer = new Enhancer();

   @Bean
    public RedisCommand initRedisCommands() {
        //设置需要创建子类的类  
        enhancer.setSuperclass(RedisCommand.class);
        enhancer.setCallback(this);
        //通过字节码技术动态创建子类实例  
        return (RedisCommand) enhancer.create();
    }*/

    @Override
    public Object intercept(Object proxy, Method method, Object[] params, MethodProxy methodProxy) throws Throwable {
        // TODO Auto-generated method stub
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            Object result = methodProxy.invoke(jedis, params);
            return result;
        } catch (Throwable e) {
            logger.debug(e.getMessage(), e);
        } finally {

            if ( jedis != null && !method.getName().equals("close")) {
                jedis.close();
            }
        }
        return null;
    }
}
